#include "Gen_ir.h"

/* High-level Definitions */
void _Program(TreeNode* root){
	//empty program
	if(root==0)
		return;
	// ExtDefList
	_ExtDefList(root->des);
}

void _ExtDefList(TreeNode* n){
	// ExtDefList -> NULL
	if(n==NULL)
		return;

	// ExtDef ExtDefList
	assert(n->des);
	_ExtDef(n->des);
	_ExtDefList(n->des->sib);
}

/* Global Variable */
void _ExtDef(TreeNode *n){
	assert(n);

	TreeNode* des = n->des;
	Type type;
	type = _Specifier(des);
	des = des->sib;

	// _Specifier SEMI
	if(strcmp(des->name,"SEMI")==0)//usually function as a type declaration? struct A;
		return;
	// _Specifier ExtDecList SEMI
	else if(strcmp(des->name,"ExtDecList")==0)
	{
        printf("extern virables detected!\n");
        assert(0);
    }
	// _Specifier _FunDec _CompSt|SEMI
	else if(strcmp(des->name,"FunDec")==0){
		Function func=_FunDec(des,type);
	
		des = des->sib;
		// _Specifier _FunDec _CompSt
		if(strcmp(des->name,"CompSt")==0)			
			_CompSt(des,func);//didn't determine interface beforehand can just use return type
		
		// _Specifier _FunDec SEMI
		else if(strcmp(des->name,"SEMI")==0){
			assert(0);//no declaration
		}
		else
			assert(0);
	}
	else
		assert(0);
}

/* Specifiers */
Type _Specifier(TreeNode *n){
	assert(n);	
	TreeNode *des = n->des;
	assert(des);

	Type type;

	// TYPE
	if(strcmp(des->name,"TYPE")==0){
		type = (Type)malloc(sizeof(struct Type_));
		type->kind = BASIC;
		if(strcmp(des->attr_val,"int")==0){
			type->basic = TYPE_INT;
		}
		else if(strcmp(des->attr_val, "float")==0){
			type->basic = TYPE_FLOAT;
		}
		else
			assert(0);
		return type;
	}
	// StructSpecifier
	else if(strcmp(des->name, "StructSpecifier")==0){
		fprintf(stderr,"Cannot translate: Code contains varibles or parameters of structure type.\n");
		exit(0);
	}
	else
		assert(0);	
}

/* Declarators */
FieldList _VarDec(TreeNode *n, Type type, From from){
	assert(n);	
	TreeNode *des = n->des;
	assert(des);

	// ID
	if(strcmp(des->name, "ID")==0){		
		FieldList varDec = (FieldList)malloc(sizeof(struct FieldList_));
		varDec->name = des->attr_val;
		varDec->type = type;
		varDec->tail = NULL;

		if(from==FROM_PARAM){
			Operand opParam=malloc(sizeof(Operand_));
			opParam->kind=VARIABLE;
			opParam->value = des->attr_val;

			InterCode pcode = malloc(sizeof(InterCode_));
			pcode->kind = IR_PARAM;
			pcode->sinop.op=opParam;
			insertCode(pcode);		

			return varDec;
		}		
		varInsertTable(varDec);
		return varDec;
	}
	// VarDec LB INT RB
	else if(strcmp(des->name, "VarDec")==0){

		Type arr = (Type)malloc(sizeof(struct Type_));
		arr->kind = ARRAY;
		arr->array.size = (int)strtol(des->sib->sib->attr_val,NULL,10);
		arr->array.elem = type; 

		return _VarDec(des, arr, from);
	}
	else
		assert(0);
}

Function _FunDec(TreeNode *n, Type type){
	assert(n);
	
	TreeNode *des = n->des;
	Function func = (Function)malloc(sizeof(struct Function_));
	assert(func);
	func->name = des->attr_val;
	func->isDefined = 0;
	func->param = NULL;
	func->r_type = type;
	func->line = des->row;

	Operand funcop=malloc(sizeof(Operand_));
	funcop->kind = FUNCTION_;
	funcop->value = func->name;

	InterCode code=malloc(sizeof(InterCode_));
	code->kind = IR_FUNC;
	code->sinop.op = funcop;
	insertCode(code);		//funtion  :


	des = des->sib->sib;
	// ID LP _VarList RP
	if(strcmp(des->name,"VarList")==0){
		func->param = _VarList(des);
	}
	return func;
}

FieldList _VarList(TreeNode *n){
	assert(n);
	
	TreeNode *des = n->des;
	// ->ParamDec
	FieldList paramList = _ParamDec(des);
	des = des->sib;
	
	// ->ParamDec COMMA _VarList 
	if(des != NULL){
		des = des->sib;
		paramList->tail = _VarList(des);
	}
	else
		paramList->tail = NULL;
	return paramList;
}

FieldList _ParamDec(TreeNode *n){
	assert(strcmp(n->name,"ParamDec")==0);	
	TreeNode *des = n->des;

	// _Specifier VarDec
	Type type = _Specifier(des);
	des = des->sib;
	assert(type);
	
	FieldList paramDec = _VarDec(des, type, FROM_PARAM);
	return paramDec;
}

/* Statements */
void _CompSt(TreeNode *n, Function BlngFunc){
	assert(n);

	StkPush();
	
	TreeNode *des = n->des;
	// LC (_DefList) (_StmtList) RC
	des = des->sib;
	if(strcmp(des->name,"DefList")==0)
	{
		_DefList(des, FROM_VARIABLE);
		des = des->sib;
	}
	if(strcmp(des->name,"StmtList")==0)
		_StmtList(des, BlngFunc);

	StkPop();
}

void _StmtList(TreeNode *n, Function BlngFunc){
	// _StmtList -> NULL
	if(n==NULL)
		return;

	TreeNode *des = n->des;
	assert(des);
	assert(strcmp(des->name,"Stmt")==0);
	
	// _Stmt _StmtList
	_Stmt(des, BlngFunc);
	_StmtList(des->sib, BlngFunc);
}

void _Stmt(TreeNode *n, Function BlngFunc){
	assert(n);
	
	TreeNode *des = n->des;
	// _Exp SEMI
	if(strcmp(des->name, "Exp")==0)
	{
		//_Exp(des,NULL);//不需要向res继续传递  瞎说 不存在的！！ 一个函数 swap() 返回值不需要赋给任何变量
		Operand tmp=malloc(sizeof(Operand_));
		tmp->kind = TEMPVAR;
		tmp->var_no= temVarNo++;

		_Exp(des,tmp);
	}
	// _CompSt
	else if(strcmp(des->name, "CompSt")==0){
		_CompSt(des, BlngFunc);
	}
	// RETURN _Exp SEMI
	else if(strcmp(des->name, "RETURN")==0){
		Operand op=malloc(sizeof(Operand_));
		op->kind = TEMPVAR;
		op->var_no= temVarNo++;

		Type expType=_Exp(des->sib,op);
		
		InterCode code = malloc(sizeof(InterCode_));
		code->kind = IR_RETURN;
		code->sinop.op = op;
		insertCode(code);
	}
	// IF LP Exp RP Stmt (ELSE Stmt)?
	else if(strcmp(des->name, "IF")==0){
		des = des->sib->sib;

		Operand lbTrue = malloc(sizeof(Operand_));
		lbTrue->kind = LABEL;
		lbTrue->valid = FALSE;
		lbTrue->var_no = labelNo++;
		Operand lbFalse = malloc(sizeof(Operand_));
		lbFalse->kind = LABEL;
		lbFalse->valid = FALSE;
		lbFalse->var_no = labelNo++;

		Type expType = Exp_Cond(des,lbTrue,lbFalse);

		InterCode lb_true=malloc(sizeof(InterCode_));
		lb_true->kind=IR_LABEL;
		lb_true->sinop.op=lbTrue;
		insertCode(lb_true);
		
		//if code
		des = des->sib->sib;
		_Stmt(des, BlngFunc);

		InterCode lb_false = malloc(sizeof(InterCode_));
		lb_false->kind = IR_LABEL;
		lb_false->sinop.op = lbFalse;

		des = des->sib;
		if(des == NULL){
			insertCode(lb_false);
			return;
		}
		assert(strcmp(des->name,"ELSE")==0);

		Operand lbEndif = malloc(sizeof(Operand_));
		lbEndif->kind = LABEL;
		lbEndif->valid = FALSE;
		lbEndif->var_no = labelNo++;

		InterCode goto_endif=malloc(sizeof(InterCode_));
		goto_endif->kind = IR_GOTO;
		goto_endif->sinop.op = lbEndif;
		insertCode(goto_endif);			//goto endif

		insertCode(lb_false);		//label for else stmt
		
		des = des->sib;
		_Stmt(des, BlngFunc);

		InterCode lb_endif=malloc(sizeof(InterCode_));
		lb_endif->kind = IR_LABEL;
		lb_endif->sinop.op = lbEndif;
		insertCode(lb_endif);		//label3
	}
	// WHILE LP _Exp RP _Stmt
	else if(strcmp(des->name, "WHILE")==0){
		Operand lbCond=malloc(sizeof(Operand_));
		lbCond->kind = LABEL;
		lbCond->valid = FALSE;
		lbCond->var_no = labelNo++;

		Operand lbTrue=malloc(sizeof(Operand_));
		lbTrue->kind = LABEL;
		lbTrue->valid = FALSE;
		lbTrue->var_no = labelNo++;
		Operand lbFalse = malloc(sizeof(Operand_));
		lbFalse->kind = LABEL;
		lbFalse->valid = FALSE;
		lbFalse->var_no = labelNo++;

		des = des->sib->sib;
		InterCode lb_cond = malloc(sizeof(InterCode_));
		lb_cond->kind = IR_LABEL;
		lb_cond->sinop.op = lbCond;
		insertCode(lb_cond);		//label:cond

		Exp_Cond(des,lbTrue,lbFalse);

		InterCode lb_true=malloc(sizeof(InterCode_));
		lb_true->kind = IR_LABEL;
		lb_true->sinop.op = lbTrue;
		insertCode(lb_true);		

		des = des->sib->sib;
		_Stmt(des, BlngFunc);

		InterCode goto_cond = malloc(sizeof(InterCode_));
		goto_cond->kind = IR_GOTO;
		goto_cond->sinop.op = lbCond;
		insertCode(goto_cond);		
		
		InterCode lb_false = malloc(sizeof(InterCode_));
		lb_false->kind = IR_LABEL;
		lb_false->sinop.op = lbFalse;
		insertCode(lb_false);		
	}
}

Type Exp_Cond(TreeNode *n,Operand label_true,Operand label_false)
{
	assert(strcmp(n->name,"Exp")==0);
	TreeNode *des = n->des;
	Type type;
	if(strcmp(des->name,"Exp")==0)
	{
		TreeNode *des_op=des->sib;
		if(strcmp(des_op->name,"RELOP")==0)
		{
			Operand t1=malloc(sizeof(Operand_));
			t1->kind=TEMPVAR;
			t1->var_no=temVarNo++;
			Operand t2=malloc(sizeof(Operand_));
			t2->kind=TEMPVAR;
			t2->var_no=temVarNo++;

			TreeNode* des_oprd1=des;
			TreeNode* des_oprd2=des_op->sib;
			Type tp1=_Exp(des_oprd1,t1);	//code1
			Type tp2=_Exp(des_oprd2,t2);	//code2
			
			InterCode if_goto_true=malloc(sizeof(InterCode_));
			if_goto_true->kind=IR_IFGOTO;
			if_goto_true->triop.x=t1;
			if_goto_true->triop.op=des_op->attr_val;
			if_goto_true->triop.y=t2;
			if_goto_true->triop.label=label_true;
			insertCode(if_goto_true);		//if_goto_true

			InterCode goto_false=malloc(sizeof(InterCode_));
			goto_false->kind=IR_GOTO;
			goto_false->sinop.op=label_false;
			insertCode(goto_false);		//goto label false
			return tp1;		
		}
		else if(strcmp(des_op->name,"AND")==0)
		{
			Operand lbNextcond=malloc(sizeof(Operand_));
			lbNextcond->kind=LABEL;
			lbNextcond->var_no=labelNo++;

			Type t=Exp_Cond(des,lbNextcond,label_false);	//code1

			InterCode lb_nextcond=malloc(sizeof(InterCode_));
			lb_nextcond->kind=IR_LABEL;
			lb_nextcond->sinop.op=lbNextcond;
			insertCode(lb_nextcond);		//label 1

			des=des_op->sib;
			Type t2=Exp_Cond(des,label_true,label_false);	//code2
			return t2;
		}
		else if(strcmp(des_op->name,"OR")==0)
		{
			Operand lbNextcond=malloc(sizeof(Operand_));
			lbNextcond->kind=LABEL;
			lbNextcond->var_no=labelNo++;

			Type t=Exp_Cond(des,label_true,lbNextcond);	//code1

			InterCode lb_nextcond=malloc(sizeof(InterCode_));
			lb_nextcond->kind=IR_LABEL;
			lb_nextcond->sinop.op=lbNextcond;
			insertCode(lb_nextcond);		//label 1

			des=des_op->sib;
			Type t2=Exp_Cond(des,label_true,label_false);	//code2
			return t2;
		}
	}
	if(strcmp(des->name,"NOT")==0)	//not
	{
		des=des->sib;
		assert(strcmp(des->name,"Exp")==0);
		Type t=Exp_Cond(des,label_false,label_true);
		return t;
	}
	if(strcmp(des->name,"LP")==0)
	{
		des=des->sib;
		assert(strcmp(des->name,"Exp")==0);
		Type t=Exp_Cond(des,label_true,label_false);
		return t;
	}
	
	printf("Attention: implicit cast to bool\n");
	//以下直接当成表达式为0 为1处理了
	Operand t1=malloc(sizeof(Operand_));
	t1->kind=TEMPVAR;
	t1->var_no=temVarNo++;
	type=_Exp(n,t1);		//code1

	Operand t2=malloc(sizeof(Operand_));
	t2->kind=CONSTANT;
	t2->value="0";

	InterCode code2=malloc(sizeof(InterCode_));
	code2->kind=IR_IFGOTO;
	code2->triop.x=t1;
	code2->triop.op= "!=";
	code2->triop.y=t2;
	code2->triop.label=label_true;
	insertCode(code2);		//code2

	InterCode goto_false=malloc(sizeof(InterCode_));
	goto_false->kind=IR_GOTO;
	goto_false->sinop.op=label_false;
	insertCode(goto_false);		//goto label false
	return type;
}

/* Local Definitions */
FieldList _DefList(TreeNode *n, From from){
	// _DefList -> NULL
	if(n==NULL)
		return NULL;
	
	TreeNode *des = n->des;
	assert(des);
	assert(strcmp(des->name,"Def")==0);

	// Def _DefList 
	FieldList defList = _Def(des, from);

	if(defList == NULL){//error virables, ignore
		defList = _DefList(des->sib, from);
		return defList;
	}

	FieldList tmp = defList;
	while(tmp->tail != NULL)
		tmp = tmp->tail;
	tmp->tail = _DefList(des->sib, from);
	return defList;
}

FieldList _Def(TreeNode *n, From from){
	assert(n);
	assert(strcmp(n->name,"Def")==0);
	
	TreeNode *des = n->des;
	// _Specifier _DecList SEMI
	
	Type type = _Specifier(des);
	des = des->sib;
	FieldList def = _DecList(des, type, from);
	return def;
}

FieldList _DecList(TreeNode *n, Type type, From from)
{
	assert(n);
	assert(strcmp(n->name,"DecList")==0);
	
	TreeNode *des = n->des;
	FieldList decList = NULL;

	decList = _Dec(des, type, from);
	des = des->sib;

	// _Dec
	if(des == NULL)
		return decList;
	// _Dec COMMA _DecList
	des = des->sib;
	if(decList==NULL){
		decList = _DecList(des, type, from);
	}
	else{
		FieldList tmpDec = decList;
		while(tmpDec->tail != NULL)
				tmpDec = tmpDec->tail;
		tmpDec->tail = _DecList(des, type, from);
	}
	return decList;
}

FieldList _Dec(TreeNode *n, Type type, From from){//返回的仅是单个节点
	assert(n);

	TreeNode *des = n->des;
	FieldList dec = _VarDec(des, type, from);

	if(dec->type->kind==ARRAY)
	{
		//array space
		Operand arr=malloc(sizeof(Operand_));
		arr->kind=ADDRESS;
		char* buffer=malloc(30);
		strcpy(buffer,"arr_");
		arr->value = strcat(buffer, dec->name);//就是数组名

		InterCode deccode=malloc(sizeof(InterCode_));
		deccode->kind=IR_DEC;
		deccode->dec.op=arr;
		deccode->dec.size=typeSize(dec->type);
		insertCode(deccode);
	}

	des = des->sib;
	// _VarDec
	if(des == NULL)
		return dec;

	// _VarDec ASSIGNOP _Exp
	assert(strcmp(des->name,"ASSIGNOP")==0);
	assert(from==FROM_VARIABLE);
	des = des->sib;

	Operand leftOp = malloc(sizeof(Operand_));
	memset(leftOp, 0, sizeof(Operand_));
	leftOp->kind=VARIABLE;
	leftOp->value=dec->name;

	Operand rightOp = malloc(sizeof(Operand_));
	memset(rightOp, 0, sizeof(Operand_));
	rightOp->kind = TEMPVAR;
	rightOp->var_no = temVarNo++;

	Type expType = _Exp(des,rightOp);	// int a = b+3;
	//已经确保类型等价了
	free(expType);

	InterCode assignCode1 = malloc(sizeof(InterCode_));
	memset(assignCode1, 0, sizeof(InterCode_));
	assignCode1->assign.left = leftOp;
	assignCode1->assign.right = rightOp;
	assignCode1->kind = IR_ASSIGN;
	insertCode(assignCode1);

	return dec;
}

int typeSize(Type type){
	if(type->kind==BASIC)
		return 4;
	else if(type->kind==ARRAY)		//array
		return	type->array.size*typeSize(type->array.elem);
	
	assert(0);
}

/* Expressions */
Type _Exp(TreeNode *n, Operand res){
	assert(n);
	
	TreeNode *des = n->des;

	if(strcmp(des->name,"LP")==0){
		//_Exp->LP _Exp RP
		des = des->sib;
		return _Exp(des, res);
	}
	
	if(strcmp(des->name,"MINUS")==0){
		//_Exp->MINUS _Exp
		Operand rightOp = malloc(sizeof(Operand_));
		memset(rightOp, 0, sizeof(Operand_));
		rightOp->kind = TEMPVAR;
		rightOp->var_no = temVarNo++;

		des = des->sib;
		Type type = _Exp(des,rightOp);
		assert(type);
		assert(type->kind==BASIC);

		Operand zeroOp =  malloc(sizeof(Operand_));
		memset(zeroOp, 0, sizeof(Operand_));
		zeroOp->kind = CONSTANT;
		zeroOp->value = "0";

		InterCode minusCode = malloc(sizeof(InterCode_));
		memset(minusCode, 0, sizeof(InterCode_));
		minusCode->binop.op1 = zeroOp;
		minusCode->binop.op2 = rightOp;
		minusCode->binop.result = res;
		minusCode->kind = IR_SUB;
		insertCode(minusCode);		

		type->assign = RIGHT;
		return type;
	}

	if(strcmp(des->name,"ID")==0){
		if(des->sib==NULL){
			//Exp->ID
			//原来res一定是个没有用的临时变量
			res->kind = VARIABLE;
			res->value = des->attr_val;
			
			return NULL;
		}
		else{
			//Exp->ID LP RP | ID LP Args RP
			assert(strcmp(des->sib->name,"LP")==0);
			Type func = getTable(des->attr_val);   //判断是否定义过
			assert(func->kind==FUNCTION);//默认没有和变量重名的

			FieldList param = func->function->param;
			des = des->sib->sib;
			if(strcmp(des->name,"RP")==0){//Exp->ID LP RP
				assert(param==NULL);

				if(strcmp(func->function->name,"read")==0){						
					InterCode funcCode = malloc(sizeof(InterCode_));
					memset(funcCode, 0, sizeof(InterCode_));
					funcCode->sinop.op = res;
					funcCode->kind = IR_READ;
					insertCode(funcCode);				
				}
				else{
					Operand funcOp = malloc(sizeof(Operand_));
					memset(funcOp, 0, sizeof(Operand_));
					funcOp->value = func->function->name;
					funcOp->kind = FUNCTION_;

					InterCode funcCode = malloc(sizeof(InterCode_));
					memset(funcCode, 0, sizeof(InterCode_));
					funcCode->assign.left = res;
					funcCode->assign.right = funcOp;
					funcCode->kind = IR_CALL;
					insertCode(funcCode);				
				}
			}
			else{//Exp->ID LP Args RP
				assert(strcmp(des->name,"Args")==0);
				Operand args=NULL;

				assert(_Args(des,param,&args)==TRUE); 
				if(strcmp(func->function->name,"write")==0){
					InterCode funcCode = malloc(sizeof(InterCode_));
					memset(funcCode, 0, sizeof(InterCode_));
					funcCode->sinop.op = args;
					funcCode->kind = IR_WRITE;
					insertCode(funcCode);
				}
				else{//一般函数
					assert(args);
					while(args!=NULL){
						InterCode argCode = malloc(sizeof(InterCode_));
						memset(argCode, 0, sizeof(InterCode_));
						argCode->sinop.op = args;//日后要注意 next域是不为NULL的
						argCode->kind = IR_ARG;
						insertCode(argCode);

						args = args->next;
					}
					Operand funcOp = malloc(sizeof(Operand_));
					memset(funcOp, 0, sizeof(Operand_));
					funcOp->value = func->function->name;
					funcOp->kind = FUNCTION_;
					
					InterCode funcCode = malloc(sizeof(InterCode_));
					memset(funcCode, 0, sizeof(InterCode_));
					funcCode->assign.left = res;
					funcCode->assign.right = funcOp;
					funcCode->kind = IR_CALL;
					insertCode(funcCode);	
				}			
			}

			Type rtn = (Type)malloc(sizeof(struct Type_));
			memcpy(rtn, func->function->r_type, sizeof(struct Type_));

			rtn->assign = RIGHT;
			return rtn;
		}
	}
	else if(strcmp(des->name,"INT")==0){
		//_Exp->INT
		Type type = (Type)malloc(sizeof(struct Type_));
		type->kind = BASIC;
		type->basic = TYPE_INT;
		type->assign = RIGHT;

//直接把原来准备的temVar改掉
		res->value = des->attr_val;
		res->kind = CONSTANT;		

		return type;
	}
	else if(strcmp(des->name,"FLOAT")==0){
		//_Exp->FLOAT
		Type type = (Type)malloc(sizeof(struct Type_));
		type->kind = BASIC;
		type->basic = TYPE_FLOAT;
		type->assign = RIGHT;

		res->value = des->attr_val;
		res->kind = CONSTANT;	

		return type;
	}
	else {
		assert(strcmp(des->name,"Exp")==0);
		//_Exp->_Exp ...		
		if(strcmp(des->sib->name,"ASSIGNOP")==0 ){
			//Exp->Exp ASSIGNOP Exp

			Operand leftOp = malloc(sizeof(Operand_));
			memset(leftOp, 0, sizeof(Operand_));
			leftOp->var_no = temVarNo++;
			leftOp->kind = TEMPVAR;
			leftOp->isRight=1;//非左值标记

			Operand rightOp = malloc(sizeof(Operand_));
			memset(rightOp, 0, sizeof(Operand_));
			rightOp->var_no = temVarNo++;
			rightOp->kind = TEMPVAR;

			Type lhs = _Exp(des,leftOp);
			Type rhs = _Exp(des->sib->sib,rightOp);
		
			InterCode assignCode1 = malloc(sizeof(InterCode_));
			memset(assignCode1, 0, sizeof(InterCode_));
			assignCode1->assign.left = leftOp;
			assignCode1->assign.right = rightOp;
			if(leftOp->isRight==0)//非左值标记被置为零
				assignCode1->kind=IR_DEREF_L;
			else
				assignCode1->kind = IR_ASSIGN;
			insertCode(assignCode1);
		
			//应该不至于有连等  省一点语句 不向回传递了
			// InterCode assignCode2 = malloc(sizeof(InterCode_));
			// memset(assignCode2, 0, sizeof(InterCode_));
			// assignCode2->assign.left = res;
			// assignCode2->assign.right = rightOp;
			// assignCode2->kind = IR_ASSIGN;
			// insertCode(assignCode2);			

			return lhs;		
		}

		if(	strcmp(des->sib->name,"PLUS")==0 || 
					strcmp(des->sib->name,"MINUS")==0 || 
						strcmp(des->sib->name,"STAR")==0 || 
							strcmp(des->sib->name,"DIV")==0){
		//_Exp->_Exp PLUS|MINUS|STAR|DIV _Exp

			Operand leftOp = malloc(sizeof(Operand_));
			memset(leftOp, 0, sizeof(Operand_));
			leftOp->var_no = temVarNo++;
			leftOp->kind = TEMPVAR;

			Operand rightOp = malloc(sizeof(Operand_));
			memset(rightOp, 0, sizeof(Operand_));
			rightOp->var_no = temVarNo++;
			rightOp->kind = TEMPVAR;

			Type lhs = _Exp(des,leftOp);
			Type rhs = _Exp(des->sib->sib,rightOp);

			InterCode calcCode = malloc(sizeof(InterCode_));
			memset(calcCode, 0, sizeof(InterCode_));
			if(strcmp(des->sib->name,"PLUS")==0)
				calcCode->kind=IR_ADD;
			else if(strcmp(des->sib->name,"MINUS")==0)
				calcCode->kind=IR_SUB;
			else if(strcmp(des->sib->name,"STAR")==0)
				calcCode->kind=IR_MUL;
			else if(strcmp(des->sib->name,"DIV")==0)
				calcCode->kind=IR_DIV;

			calcCode->binop.op1 = leftOp;
			calcCode->binop.op2 = rightOp;
			calcCode->binop.result = res;
			insertCode(calcCode);
			
			return lhs;
		}
		
		if(strcmp(des->sib->name,"LB")==0){
			//_Exp->_Exp LB _Exp RB
			TreeNode *p = des->des;
			for ( ; strcmp(p->name,"ID") != 0; p = p->des);//这里只为把数组名字找出来
			
			Operand opBase = malloc(sizeof(Operand_));
			memset(opBase, 0, sizeof(Operand_));
			opBase->kind = ADDRESS;
			char* buffer=malloc(30);
			strcpy(buffer,"arr_");
			opBase->value = strcat(buffer,p->attr_val);

			Operand opB = malloc(sizeof(Operand_));	//opB := &opBase
			memset(opB, 0, sizeof(Operand_));
			opB->var_no = temVarNo++;
			opB->kind = TEMPVAR;

			InterCode assignCode1 = malloc(sizeof(InterCode_));
			memset(assignCode1, 0, sizeof(InterCode_));
			assignCode1->assign.left = opB;
			assignCode1->assign.right = opBase;
			assignCode1->kind = IR_ADDR;
			insertCode(assignCode1);//opB := &opBase
			
			// Operand opOffset = malloc(sizeof(Operand_));
			// memset(opOffset, 0, sizeof(Operand_));
			// opOffset->var_no = temVarNo++;
			// opOffset->kind = TEMPVAR;

			Operand opOffset=NULL;//计算完computeOffset之后 会指向堆空间的一块内存
			computeOffset(des, &opOffset);//_Exp->_Exp LB _Exp RB 中的第一个Exp
			assert(opOffset);

			Operand opConst4=malloc(sizeof(Operand_));
			opConst4->kind=CONSTANT;
			opConst4->value="4";
				
			Operand opOffset_byte = malloc(sizeof(Operand_));
			memset(opOffset_byte, 0, sizeof(Operand_));
			opOffset_byte->var_no = temVarNo++;
			opOffset_byte->kind = TEMPVAR;

			InterCode codeMul=malloc(sizeof(InterCode_));
			codeMul->kind=IR_MUL;
			codeMul->binop.op1 = opConst4;
			codeMul->binop.op2 = opOffset;
			codeMul->binop.result = opOffset_byte;
			insertCode(codeMul);

			Operand res_addr = malloc(sizeof(Operand_));
			memset(res_addr, 0, sizeof(Operand_));
			res_addr->var_no = temVarNo++;
			res_addr->kind = TEMPVAR;

			InterCode codeAddr=malloc(sizeof(InterCode_));
			codeAddr->kind=IR_ADD;
			codeAddr->binop.op1 = opB;
			codeAddr->binop.op2 = opOffset_byte;
			assert(res);//应该不会有人没事只写一个 a[3]的
			codeAddr->binop.result = res_addr;
			insertCode(codeAddr);

			if(res->isRight==0)//  x = a[]
			{
				InterCode codeDeref=malloc(sizeof(InterCode_));
				codeDeref->kind=IR_DEREF_R;  //x := *addr
				codeDeref->assign.left = res;
				codeDeref->assign.right = res_addr;
				insertCode(codeDeref);
			}
			else//左值  valid之前memcpy已经恢复成0了
			{
				*res=*res_addr;				
			}

			Type rtn = (Type)malloc(sizeof(struct Type_));
			rtn->kind = BASIC;
			rtn->basic = TYPE_INT;
			rtn->assign = BOTH;
			return rtn;
		}

		printf("喵喵喵？ 那第二个符号是?%s\n",des->sib->name);
		assert(0);
	}
	printf("why don't you return?\n");
	printf("喵喵喵？ 还能是？%s?\n",des->name);
	assert(0);
}

int computeOffset(TreeNode* exp, Operand* res)//需要返回的偏移量在res里  返回值为这一层数组的size，如果递归调用会用到  初始传进来的res为未参与任何运算的一个新的operand
{
	//exp为 Exp LB _Exp RB 中的第一个Exp
	assert(strcmp(exp->name,"Exp")==0);
	Type array=Exp(exp);//因为不能递归 只能用Semantic中的函数 也可以对des处理 返回一个type 函数最终将返回 array->array.size 为下一层做好准备
	assert(array->kind==ARRAY);//是在之前声明的时候算好的

	Operand opIndex = malloc(sizeof(Operand_));
	memset(opIndex, 0, sizeof(Operand_));
	opIndex->var_no = temVarNo++;
	opIndex->kind = TEMPVAR;
	
	//计算本层是增量是几
	TreeNode* index = exp->sib->sib;//第二个exp
	Type arrayNumber = _Exp(index,opIndex);

	if(strcmp(exp->des->name,"ID")==0)
	{
		*res=opIndex;
		//之前写的直接传Operand *res=*opIndex 然后
		//free(opIndex);//完全是空的     之前insertCode已经把这个地址记录进去了！！！  不能随便free啊啊啊   因而在后面调出了很奇怪的bug
		return array->array.size;
	}
	else
	{
		assert(strcmp(exp->des->name,"Exp")==0);

		Operand opOffset = malloc(sizeof(Operand_));
		memset(opOffset, 0, sizeof(Operand_));
		opOffset->var_no = temVarNo++;
		opOffset->kind = TEMPVAR;

		int size=computeOffset(exp->des, opOffset);

		Operand opSize=malloc(sizeof(Operand_));
		opSize->kind=CONSTANT;
		opSize->value=malloc(16);
		sprintf(opSize->value, "%d", size);

		Operand res1 = malloc(sizeof(Operand_));
		memset(res1, 0, sizeof(Operand_));
		res1->var_no = temVarNo++;
		res1->kind = TEMPVAR;

		InterCode codeMul=malloc(sizeof(InterCode_));
		codeMul->kind=IR_MUL;
		codeMul->binop.op1 = opOffset;
		codeMul->binop.op2 = opSize;
		codeMul->binop.result = res1;
		insertCode(codeMul);
		
		Operand res2 = malloc(sizeof(Operand_));
		memset(res2, 0, sizeof(Operand_));
		res2->var_no = temVarNo++;
		res2->kind = TEMPVAR;

		InterCode codeAdd=malloc(sizeof(InterCode_));
		codeAdd->kind=IR_ADD;
		codeAdd->binop.op1 = res1;
		codeAdd->binop.op2 = opIndex;
		codeAdd->binop.result = res2;
		insertCode(codeAdd);

		*res=res2;//原来的完全是空的  res2刚刚在InterCode里才用的   没有free  和insertCode里面实际地址不完全一样 然而内容是一样的 或许会有小问题 先不管了
		return array->array.size;
	}
}

bool _Args(TreeNode *n, FieldList param, Operand* arg_pr){
	assert(n);
	assert(strcmp(n->name,"Args")==0);
	
	Operand arg=malloc(sizeof(struct Operand_));
	arg->kind = TEMPVAR;
	arg->var_no = temVarNo++;
	arg->next=*arg_pr;

	*arg_pr=arg;

	TreeNode *des = n->des;
	//Args -> _Exp COMMA Args | _Exp
	Type tmpParam = _Exp(des, arg);

	if(des->sib==NULL)
		if(param->tail==NULL)
			return TRUE;
		else
			//fewer params
			return FALSE;
	else
		return _Args(des->sib->sib, param->tail, arg_pr);
}

